package code.google.jcontainer.resolver;

import code.google.jcontainer.AbstractContainer;
import code.google.jcontainer.util.AnnotationRepository;

import java.lang.annotation.Annotation;
import java.util.HashMap;
import java.util.Map;

/**
 * Context object for resolving annotation.<br>
 * ResolveContext will be passed among AnnotationResolves of a method/filed, and it can carry user data by using set/getUserData method. 
 *
 * @author <a href="mailto:jfox.young@gmail.com">Young Yang</a>
 */
public abstract class ResolveContext {

    /**
     * The container
     */
    private AbstractContainer container = null;

    /**
     * component name
     */
    private String componentName;

    /**
     * Component class
     */
    private Class componentClass;
    
    /**
     * Component instance
     */
    private Object component;

    /**
     * annotation want to resolve
     */
    private Annotation annotation;

    /**
     * user data map set user during resolving annotation <br>
     * datas can be transferred among many Class/Method/Field annotation
     */
    private Map<String, Object> userDatas = new HashMap<String, Object>(5);


    public ResolveContext(AbstractContainer container, String componentName, Class componentClass, Object component) {
        this.container = container;
        this.componentName = componentName;
        this.componentClass = componentClass;
        this.component = component;
    }

    public AbstractContainer getContainer() {
        return container;
    }

    public String getComponentName() {
        return componentName;
    }

    /**
     * return component class
     */
    public Class getComponentClass() {
        return componentClass;
    }

    /**
     * Get other component from Container by name
     * Sometimes, may need to get component by name during resolving annotation 
     */
    public Object getComponent(String name) {
        return getContainer().getComponent(name);
    }

    /**
     * return AnnotationResolverRepository used in this container
     */
    public AnnotationResolverRepository getAnnotationResolverRepository() {
        return getContainer().getAnnotationResolverRepository();
    }

    /**
     * return AnnotationRepository used in this container
     */
    public AnnotationRepository getAnnotationRepository() {
        return getContainer().getAnnotationRepository();
    }

    /**
     * return the component
     */
    public Object getComponent() {
        return component;
    }

    /**
     * return the annotation to resolve
     */
    public Annotation getAnnotation() {
        return annotation;
    }

    /**
     * set the annotation to resolve <br>
     * only call by container, don't call this method during resolve
     */
    public void setAnnotation(Annotation annotation) {
        this.annotation = annotation;
    }

    /**
     * set user data, datas can be transferred among many Class/Method/Field annotation
     */
    public void setUserData(String key, Object value) {
        userDatas.put(key, value);
    }

    /**
     * return user data by key, datas can be transferred among many Class/Method/Field annotation
     */
    public Object getUserData(String key) {
        return userDatas.get(key);
    }
    
}
